package com.runa.monitor.platinterface.netservice.equipment;

import com.runa.monitor.comm.dto.*;
import com.runa.monitor.platinterface.backwork.function.TaskFunction;
import com.runa.monitor.platinterface.netservice.connect.commstatus.CommStatus;
import com.runa.rccprotocol.dto.ConcentratorRequestDataProxy;
import com.runa.rccprotocol.dto.equdata.EquData;
import com.runa.rccprotocol.dto.huanxiang.HuanXiangEquRequestData;
import com.runa.rccprotocol.dto.huanxiang.HuanXiangFmuRequestData;
import com.runa.rccprotocol.dto.param.ExtendParam;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @author diandian
 * @Date 2022/5/20 13:35
 */
@Slf4j
public class HuanXiangDriver extends NetEqu<String> {
    private HuanXiangEquRequestData equRequestData;
    private HuanXiangFmuRequestData fmuRequestData;

    public HuanXiangDriver(String ip, short port, String serial, Integer timeout) {
        super(serial, timeout);
        this.equRequestData = new HuanXiangEquRequestData(serial);
        this.fmuRequestData = new HuanXiangFmuRequestData(ip, port, serial, equRequestData);
    }

    private void readBuildValve(List<Node> buildValves, TaskFunction function) {
        short baudRate = 2400;
        for (Node node : buildValves) {
            equRequestData.readValve(node.getSerial());
            this.fmuRequestData.initRequest(node.getPort(), baudRate, (byte) 0x02);
            ConcentratorRequestDataProxy dataProxy = new ConcentratorRequestDataProxy(serial(), fmuRequestData);
            dataProxy.setRemain(Collections.singletonList(node));
            sendRequest(dataProxy, function);
        }
    }

    private void readBuildMeter(List<Node> buildMeters, TaskFunction function) {
        readHouseMeter(buildMeters, function);
    }

    private void readHouseMeter(List<Node> meters, TaskFunction function) {
        for (Node node : meters) {
            if ("HX-HM".equalsIgnoreCase(node.getModel())) {
                equRequestData.readHouseMeter_Modbus(node.getSerial());
                this.fmuRequestData.initRequest(node.getPort(), (short) 9600, (byte) 0x2);
            } else {
                equRequestData.readHouseMeter(node.getSerial());
                this.fmuRequestData.initRequest(node.getPort(), (short) 2400, (byte) 0x2);
            }
            ConcentratorRequestDataProxy dataProxy = new ConcentratorRequestDataProxy(serial(), fmuRequestData);
            dataProxy.setRemain(Collections.singletonList(node));
            sendRequest(dataProxy, function);
        }
    }

    private void readHouseValve(List<Node> valves, TaskFunction function) {
        short baudRate = 2400;
        for (Node node : valves) {
            equRequestData.readValve(node.getSerial());
            this.fmuRequestData.initRequest(node.getPort(), baudRate, (byte) 0x02);
            ConcentratorRequestDataProxy dataProxy = new ConcentratorRequestDataProxy(serial(), fmuRequestData);
            dataProxy.setRemain(Collections.singletonList(node));
            sendRequest(dataProxy, function);
        }
    }


    @Override
    public void readNodeEqu(List<Node> nodeList, TaskFunction function, EquData.EquDataType type) {
        if (!online()) {
            function.doApply(CommStatus.OffLine, nodeList);
            return;
        }
        switch (type) {
            case PUBLIC_UNIT:
                readBuildValve(nodeList, function);
                break;
            case VALVE:
                readHouseValve(nodeList, function);
                break;
            case METER:
                readHouseMeter(nodeList, function);
                break;
            default:
        }

    }

//    public Node findUnit(String serial) {
//        for (Node node : buildValves) {
//            if (serial.equals(node.getSerial())) {
//                return node;
//            }
//        }
//        return null;
//    }
//
//    public Node findMeter(String serial) {
//        for (Node node : meters) {
//            if (serial.equals(node.getSerial())) {
//                return node;
//            }
//        }
//        for (Node node : buildMeters) {
//            if (serial.equals(node.getSerial())) {
//                return node;
//            }
//        }
//        return null;
//    }

    @Override
    public void setNodeEquArchive(List<Archive> archives, TaskFunction function) {

    }

    @Override
    public void clearNodeEquArchive(TaskFunction function) {

    }

    @Override
    public void valveOnOffControl(List<Node> valves, boolean ifLock, Integer opening, TaskFunction function) {
        if (!online()) {
            function.doApply(CommStatus.OffLine, valves);
            return;
        }
        boolean ctr = opening > 0;
        short baudRate = 2400;
        for (Node valve : valves) {
            if (valve != null) {
                equRequestData.valveCtrl(valve.getSerial(), ctr, ifLock);
                this.fmuRequestData.initRequest(valve.getPort(), baudRate, (byte) 0x02);
                ConcentratorRequestDataProxy dataProxy = new ConcentratorRequestDataProxy(serial(), fmuRequestData);
                dataProxy.setRemain(valve);
                sendRequest(this.equRequestData, function);
            }
        }
    }

//    public Valve findValve(String serial) {
//        for (Node valve : valves) {
//            if (serial.equals(valve.getSerial())) {
//                return (Valve) valve;
//            }
//        }
//        return null;
//    }
//
//    @Override
//    public TempPanel findPanel(String serial) {
//        return null;
//    }

    @Override
    public void readNodeRecord(List<Integer> indexes, TaskFunction function) {

    }

    @Override
    public void sentPublicUnitRecord(List<Node> valves, Integer model, Map param, TaskFunction function) {
        if (!online()) {
            function.doApply(CommStatus.OffLine, valves);
            return;
        }
        short baudRate = 2400;
        for (Node valve : valves) {
//            Node valve = findUnit(serial);
            if (valve != null) {
                switch (model) {
                    case 1:
                        String targetValue = param.get("targetValue").toString();
                        equRequestData.buildValveCtr(valve.getSerial(), new BigDecimal(targetValue).intValue());
                        this.fmuRequestData.initRequest(valve.getPort(), baudRate, (byte) 0x02);
                        ConcentratorRequestDataProxy dataProxy = new ConcentratorRequestDataProxy(serial(), fmuRequestData);
                        dataProxy.setRemain(valve);
                        sendRequest(dataProxy, function);
                        break;
                    case 2:
                    case 3:
                    case 4:
                        break;
                    default:
                }

            }
        }

    }

    @Override
    public void sentPublicUnitModel(List<Node> valveSerial, boolean model, TaskFunction function) {

    }

    @Override
    public void sentExtendParam(ExtendParam param, TaskFunction function) {

    }

    @Override
    public void readPublicUnitRecord(Node valveSerial, Integer model, TaskFunction function) {

    }

    @Override
    public void readPublicUnitAndMeter(Node valveSerial, Node meterSerial, TaskFunction function) {

    }

    @Override
    public void heartbeatUpdate() {

    }

    @Override
    public boolean heartStop() {
        return false;
    }
}